package com.meilai.project.service.app.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.meilai.project.constant.InstallTypeEnum;
import com.meilai.project.dto.app.QueryWorkOrderProgressDTO;
import com.meilai.project.dto.app.WorkerQueryWorkOrderDTO;
import com.meilai.project.entity.business.building.BuildingArea;
import com.meilai.project.entity.business.installOrder.VWorkOrderBuildingMediaNums;
import com.meilai.project.entity.business.installOrder.WorkOrder;
import com.meilai.project.entity.business.installOrder.WorkerSubmitPhoto;
import com.meilai.project.entity.media.VMediaPointDetail;
import com.meilai.project.mapper.business.building.BuildingAreaMapper;
import com.meilai.project.mapper.business.installOrder.VWorkOrderBuildingMediaNumsMapper;
import com.meilai.project.mapper.business.installOrder.WorkOrderMapper;
import com.meilai.project.mapper.media.VMediaPointDetailMapper;
import com.meilai.project.service.app.AppWorkerService;
import com.meilai.project.service.business.installOrder.WorkerSubmitPhotoService;
import com.meilai.project.util.ThreadLocalUserUtil;
import com.meilai.project.vo.app.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 张驰
 * @date 2021/10/31 0:33
 */
@Service
public class AppWorkerServiceImpl implements AppWorkerService {

    @Autowired
    private WorkOrderMapper workOrderMapper;
    @Autowired
    private VWorkOrderBuildingMediaNumsMapper numsMapper;
    @Autowired
    private VMediaPointDetailMapper pointDetailMapper;
    @Autowired
    private BuildingAreaMapper buildingAreaMapper;
    @Autowired
    private WorkerSubmitPhotoService workerSubmitPhotoService;

    @Override
    public WorkerIndexVO getWorkerIndexInfo() {

        Long worker_id = ThreadLocalUserUtil.get().getId();
        WorkerIndexVO result = workOrderMapper.getAppIndexCountInfo(worker_id != null ? worker_id : -1L);
        List<WorkerIndexWorkOrderProcessingVO> wos = workOrderMapper.getAppIndexProcessingWorkOrders();
        if (CollectionUtils.isNotEmpty(wos)) {
            wos.forEach(d -> {
                d.setWork_order_type_name(InstallTypeEnum.getName(d.getWork_order_type_id()));
                d.setWork_order_type_id(InstallTypeEnum.getOldType(d.getWork_order_type_id()));
            });
            result.setWork_order_processing_list(wos);
        }

        return result;
    }

    @Override
    public Page<WorkerQueryWorkOrderVO> queryWorkOrderList(WorkerQueryWorkOrderDTO dto) {
        Page<WorkerQueryWorkOrderVO> page = new Page<WorkerQueryWorkOrderVO>(dto.getPage(), dto.getPage_size());
        List<WorkerQueryWorkOrderVO> list = workOrderMapper.selectPageListForApp(page, dto);
        return page.setRecords(list);
    }

    @Override
    public WorkerQueryWorkOrderProgressVO queryWorkOrderProgress(QueryWorkOrderProgressDTO dto) {
        WorkerQueryWorkOrderProgressVO result = new WorkerQueryWorkOrderProgressVO();
        List<VWorkOrderBuildingMediaNums> nums = numsMapper.selectList(new QueryWrapper<VWorkOrderBuildingMediaNums>().eq("id", dto.getWork_order_id())
                .eq("building_area_id", dto.getBuilding_area_id()).eq("media_type_id", dto.getMedia_type_id()));
        if (CollectionUtils.isNotEmpty(nums) && nums.size() == 1) {
            result.setAll_count(nums.get(0).getTotal_num());
            result.setSubmit_count(nums.get(0).getInstalled_total_num());
            result.setRemain_count(nums.get(0).getTotal_num() - nums.get(0).getInstalled_total_num());

            WorkOrder wo = workOrderMapper.selectById(dto.getWork_order_id());
            if (wo != null) {
                if (!wo.getWork_order_type_id().equals(InstallTypeEnum.INSTALL.getInstallType())) {
                    // 非新安装工单时，才有具体点位
                    result.getExact_devices().setCount(result.getAll_count());
                    List<VMediaPointDetail> submitPoints = pointDetailMapper.getSubmitPointsByWorkOrderId(dto.getWork_order_id());
                    HashSet<Long> submitIds = new HashSet<>();
                    if (CollectionUtils.isNotEmpty(submitPoints)) {
                        for (VMediaPointDetail p : submitPoints) {
                            WorkerQueryWorkOrderProgressExactDeviceVO vo = new WorkerQueryWorkOrderProgressExactDeviceVO();
                            BeanUtils.copyProperties(p, vo);
                            result.getExact_devices().getSubmit().add(vo);
                            submitIds.add(p.getId());
                        }
                    }
                    List<VMediaPointDetail> unSubmitBuildingPoints = pointDetailMapper.getNotSubmitBuildingPoints(dto.getWork_order_id(), dto.getBuilding_area_id(), submitIds);
                    if (CollectionUtils.isNotEmpty(unSubmitBuildingPoints)) {
                        for (VMediaPointDetail p : unSubmitBuildingPoints) {
                            WorkerQueryWorkOrderProgressExactDeviceVO vo = new WorkerQueryWorkOrderProgressExactDeviceVO();
                            BeanUtils.copyProperties(p, vo);
                            result.getExact_devices().getRemain().add(vo);
                        }
                    }
                    List<VMediaPointDetail> unSubmitChoosePoints = pointDetailMapper.getNotSubmitChoosePoints(dto.getWork_order_id(), dto.getBuilding_area_id(), submitIds);
                    if (CollectionUtils.isNotEmpty(unSubmitChoosePoints)) {
                        for (VMediaPointDetail p : unSubmitChoosePoints) {
                            WorkerQueryWorkOrderProgressExactDeviceVO vo = new WorkerQueryWorkOrderProgressExactDeviceVO();
                            BeanUtils.copyProperties(p, vo);
                            result.getExact_devices().getRemain().add(vo);
                        }
                    }
                }
            }
        }
        return result;
    }

    @Override
    public Page<WorkerQueryWorkOrderVO> getWorkOrderListByApp(WorkerQueryWorkOrderDTO dto) {
        Long worker_id = ThreadLocalUserUtil.get().getId();
        ;
        Page<WorkerQueryWorkOrderVO> page = new Page<WorkerQueryWorkOrderVO>(dto.getPage(), dto.getPage_size());
        List<WorkerQueryWorkOrderVO> list = workOrderMapper.getWorkOrderList(page, dto, worker_id);
        return page.setRecords(list);
    }

    @Override
    public List<WorkMediaPointNoInstallVO> getOrderNoInstallByApp(Long orderId, Long building_area_id) {
        return workOrderMapper.getDeviceNoInstallByOrderId(orderId, building_area_id);
    }

    @Override
    public IPage<WorkMediaPointDetailVO> getOrderDetailByApp(Long orderId, Boolean isSubmitted, String code, Long building_area_id, Integer work_order_type_id, Integer current_page, Integer page_size) {
        Long worker_id = ThreadLocalUserUtil.get().getId();
        Page<WorkMediaPointDetailVO> page = new Page<WorkMediaPointDetailVO>(current_page, page_size);
        List<WorkMediaPointDetailVO> list = new ArrayList<>();
        if (isSubmitted) {
            list = workOrderMapper.getOrderSubmittedDeviceDetail(orderId, code, building_area_id, worker_id, work_order_type_id, page);
        } else {
            list = workOrderMapper.getOrderNotSubmittedDeviceDetail(orderId, code, building_area_id, worker_id, page);
        }
        if (isSubmitted && CollectionUtils.isNotEmpty(list)) {
            Set<Long> ids = list.stream().map(WorkMediaPointDetailVO::getLightbox_audit_id).collect(Collectors.toSet());
            if (CollectionUtils.isNotEmpty(ids)) {
                List<WorkerSubmitPhoto> photos = workerSubmitPhotoService.list(Wrappers.<WorkerSubmitPhoto>lambdaQuery().in(WorkerSubmitPhoto::getWorker_submit_id, ids));
                if (CollectionUtils.isNotEmpty(photos)) {
                    Map<Long, List<String>> img_list_map = photos.stream().collect(Collectors.groupingBy(WorkerSubmitPhoto::getWorker_submit_id, Collectors.mapping(WorkerSubmitPhoto::getUrl, Collectors.toList())));
                    list.forEach(item -> {
                        item.setImg_list(img_list_map.getOrDefault(item.getLightbox_audit_id(), new ArrayList<>()));
                    });
                }
            }
        }
        return page.setRecords(list);
    }

    @Override
    public IPage<JSONObject> getBuildingByOrderIdAndOrderType(Long work_order_id, Integer work_order_type_id, String building_name, Integer page, Integer page_size) {
        /**
         * {id:楼盘id, name:楼盘名称, address:楼盘具体地址, order_id:工单id, order_name:工单名称, order_type:工单类型id, order_type_name:工单类型}
         */
        Long worker_id = ThreadLocalUserUtil.get().getId();
        Page<JSONObject> pageObj = new Page<JSONObject>(page, page_size);
        List<Long> ids = workOrderMapper.getBuildingByBuildIdAndOrderId(pageObj, null, work_order_id, work_order_type_id, worker_id, building_name, null);
        for (Long id : ids) {
            System.out.print(id + ",");
        }
        System.out.println();
        if (CollectionUtils.isEmpty(ids)) {
            return pageObj;
        }
        return pageObj.setRecords(workOrderMapper.getBuildingByBuildIdAndOrderIdAndOrderType(null, work_order_id, work_order_type_id, worker_id, building_name, null, ids));
    }

    @Override
    public IPage<JSONObject> getBuildingList(String code, Integer page, Integer page_size) {
        Long worker_id = ThreadLocalUserUtil.get().getId();
        Page<BuildingArea> pageObj = new Page(page, page_size);
        List<BuildingArea> records = buildingAreaMapper.listBuildingOnWorkerId(pageObj, worker_id, code);
        pageObj.setRecords(records);
        /**
         * 封装返回数据
         * {id:楼盘id, name:楼盘名称, address:楼盘具体地址, list:[{order_id:工单id, order_name:工单名称, order_type:工单类型id, order_type_name:工单类型}]}
         */
        List<JSONObject> list = new ArrayList<>();
        for (BuildingArea o : records) {
            List<JSONObject> orderList = workOrderMapper.getBuildingByBuildIdAndOrderIdAndOrderType(o.getId(), null, null, worker_id, null, "1", null);
            HashMap<Long, JSONObject> map_customer = new HashMap<>();
            HashMap<Long, JSONArray> map_no_customer = new HashMap<>();
            for (JSONObject order : orderList) {
                Long customer_id = order.getLong("customer_id");
                if (map_customer.get(customer_id) == null) {
                    JSONArray arr = new JSONArray();
                    arr.add(order);
                    if (customer_id == -1) {
                        map_no_customer.put(customer_id, arr);
                    } else {
                        JSONObject map = new JSONObject();
                        map.put("id", customer_id);
                        map.put("name", order.getString("customer_name"));
                        map.put("list", arr);
                        map_customer.put(customer_id, map);
                    }
                } else {
                    if (customer_id == -1) {
                        map_no_customer.get(customer_id).add(order);
                    } else {
                        map_customer.get(customer_id).getJSONArray("list").add(order);
                    }
                }
            }

            List<JSONObject> list_customer = map_customer.values().stream().collect(Collectors.toList());
            JSONArray list_no_customer = map_no_customer.get(-1l);

            JSONObject obj = new JSONObject();
            obj.put("id", o.getId());
            obj.put("name", o.getName());
            obj.put("address", o.getAddress());
            obj.put("lat", o.getLat());
            obj.put("lng", o.getLng());
            obj.put("list_customer", list_customer);
            obj.put("list", list_no_customer);
            list.add(obj);
        }
        Page<JSONObject> pageObjNew = new Page(page, page_size);
        pageObjNew.setCurrent(pageObj.getCurrent());
        pageObjNew.setPages(pageObj.getPages());
        pageObjNew.setSize(pageObj.getSize());
        pageObjNew.setTotal(pageObj.getTotal());
        return pageObjNew.setRecords(list);
    }

    @Override
    public IPage<JSONObject> getBuildingDeviceList(Long building_area_id, String code, Integer page, Integer page_size) {
        Page<JSONObject> pageObj = new Page(page, page_size);
        List<JSONObject> list = workOrderMapper.getBuildingDeviceList(pageObj, building_area_id, code);
        for (JSONObject o : list) {
            List<JSONObject> orderList = workOrderMapper.getBuildingOrderList(building_area_id, o.getLong("id"));
            Boolean hasSubmit = false, hasReplace = false;
            for (JSONObject o2 : orderList) {
                if (o2.getInteger("flow_status") == 0) hasSubmit = true;
                if (o2.getInteger("flow_status") == 0 && o2.getLong("order_type") == 2L) hasReplace = true;
                if (hasSubmit && hasReplace) break;
            }
            o.put("list", orderList);
            o.put("hasSubmit", hasSubmit);
            o.put("hasReplace", hasReplace);
        }
        return pageObj.setRecords(list);
    }

    @Override
    public JSONArray getOrderByDevice(Long device_id) {
        return JSONArray.parseArray(JSON.toJSONString(workOrderMapper.getOrderByDevice(device_id)));
    }
}
